
#include <jni.h>
#include <string.h>
#include <stdlib.h>
#include "FwbConf.h"
#include "DntPlatform.h"
#define TAG "DntTest"

uint16_t gLogPort = 0;
uint32_t gLogIpv4 = 0;
uint8_t* gRegDat;
DNT_INFO mInfo;

#if defined(_WIN32) || defined(_WIN64)		
#include "windows.h"
#define logd(...) printf (__VA_ARGS__)

#else														// #if defined(_WIN32) || defined(_WIN64)	
#include <android/log.h>
#define logd(...) __android_log_print(ANDROID_LOG_DEBUG, "MSYS", __VA_ARGS__)
void CloudLogExtern(char* text, int length) {				// 输出日志文字 必须在用户的主程序之中实现函数功能
	DNT_INFO* info = DntGetInfo();							// 获取DNT_INFO*
	if (info != NULL && gLogPort != 0) {
		PlatformUdpSendTo(info->Socket, (uint8_t*)text, length, gLogPort, gLogIpv4);
	}
	else {
		logd("LogExtern length:%d %s", length, text);
	}
}
#endif														// #if defined(_WIN32) || defined(_WIN64)		

bool setInit(uint32_t dnIpv4[8], int dnQty) {
	int svrIdx = 0;			// 保存登录的云控域名服务器
	if (PlatformInit(&mInfo, svrIdx, NULL)) {		// 云控平台初始化
		//mTEST.Info.SvrFixed = DbsGetMemValue("svrFixed");	// 固定的服务器域名，一般用于测试
		DntSetGateway(dnIpv4, dnQty);
		DntSetIdleFlag(DNT_RB_LOGIN);
		return true;
	}
	return false;
}


extern "C" JNIEXPORT jint JNICALL Java_ltd_kcdevice_base_Dnt_polling(JNIEnv * env, jobject jobj) {
	uint8_t bytes[NET_SEND_BYTE_MAX];
	int bit = DntPolling(bytes);									// 云控轮询
	if (bit == DNT_BIT_NONE) {
		int port;
		int length = PlatformUdpRecv(mInfo.Socket, bytes, &port);
		if (length > 0) {
			//logd("polling port:%d length:%d", port, length);
			bit = DntReceive(bytes, length, port);		// 云控接收
		}
	}
	if (bit & DNT_BIT_OK_JOIN_G) {
		//CLOGI(TAG, "Receive OK_JOIN_G %02x %02x", bit, mpDNT->IdleFlag);
		//logd("polling bit:%02x IdleFlag:%02x", bit, mpDNT->IdleFlag);
		if (mpDNT->IdleFlag & DNT_RB_REG_RD) {
			DNT_INFO* info = DntGetInfo();					// 获取DNT_INFO*
			DntSetFunction(gRegDat, info->RegSize, NULL, info->MsgSize);	// 登录成功时调用一次
		}
//		bit &= ~DNT_BIT_OK_JOIN_G;
	}
	if (bit & DNT_BIT_REG_RD) {
		CLOGW(TAG, "Receive REG_RD %02x %02x%02x", bit, mpDNT->RegSize, mpDNT->Register[0], mpDNT->Register[1]);
		if (gRegDat != NULL) {
			memcpy(gRegDat, mpDNT->Register, mpDNT->RegSize);
		}
		//logd("polling bit:%02x IdleFlag:%02x", bit, mpDNT->IdleFlag);
	}
	return bit;
}
extern "C" JNIEXPORT void JNICALL Java_ltd_kcdevice_base_Dnt_writeReg(JNIEnv * env, jobject jobj) {
	DntSetIdleFlag(DNT_RB_REG_WR);
}
extern "C" JNIEXPORT void JNICALL Java_ltd_kcdevice_base_Dnt_setIdleFlag(JNIEnv * env, jobject jobj, jint flag) {
	DntSetIdleFlag((DNT_RUN_BIT)flag);
}

extern "C" JNIEXPORT void JNICALL Java_ltd_kcdevice_base_Dnt_setLogin(JNIEnv * env, jobject jobj, jstring acctName, jstring psw, jstring nickName) {
	char* ian = (char*)env->GetStringUTFChars(acctName, 0);
	char* ipsw = (char*)env->GetStringUTFChars(psw, 0);
	char* inn = (char*)env->GetStringUTFChars(nickName, 0);
	uint8_t bytes[NET_SEND_BYTE_MAX];
	DntSetLogin(bytes, ian, ipsw, DNT_ROLE_CONTROL, inn);
}
extern "C" JNIEXPORT void JNICALL Java_ltd_kcdevice_base_Dnt_ddnsLogin(JNIEnv * env, jobject jobj, jstring acctName, jstring psw) {
	char* ian = (char*)env->GetStringUTFChars(acctName, 0);
	char* ipsw = (char*)env->GetStringUTFChars(psw, 0);
	uint8_t bytes[NET_SEND_BYTE_MAX];
	DntSetLogin(bytes, ian, ipsw, DNT_ROLE_DDNS, (char*)"nickName");
}
extern "C" JNIEXPORT void JNICALL Java_ltd_kcdevice_base_Dnt_joinGroup(JNIEnv * env, jobject jobj, jstring devName, jstring visit) {
	char* idn = (char*)env->GetStringUTFChars(devName, 0);
	char* igv = (char*)env->GetStringUTFChars(visit, 0);
	uint8_t bytes[NET_SEND_BYTE_MAX];
	DntJoinGroup(bytes, idn, igv);
}
extern "C" JNIEXPORT jstring JNICALL Java_ltd_kcdevice_base_Dnt_setDns(JNIEnv * env, jobject jobj, jstring text, jint logPort, jint logIp) {
	char bytes[32];
	char* itxt = (char*)env->GetStringUTFChars(text, 0);
	int ilen = env->GetStringLength(text);
	char* array[8];
	uint32_t dnIpv4[8] = { 0 };
	gLogIpv4 = logIp;
	gLogPort = (uint16_t)logPort;
	logd("setDns itxt:%s ilen:%d port:%d ip:%08x", itxt, ilen, logPort, logIp);
	int dnQty = TxtKeyArray((size_t*)array, itxt, ilen, '`', 1);
	bool init = false;
	if (dnQty < 8) {
		for (int index = 0; index < dnQty; index++) {
			dnIpv4[index] = NetIpToInt(array[index]);
		}
		init = setInit(dnIpv4, dnQty);
		logd("setDns dnQty:%d init:%d", dnQty, init);
	}
	TxtStrCpy(bytes, sizeof(bytes), init ? (char*)"ok" : (char*)"error");
	return env->NewStringUTF(bytes);
}
extern "C" JNIEXPORT jstring JNICALL Java_ltd_kcdevice_base_Dnt_jniStart(JNIEnv * env, jobject jobj, jstring text, jobject regDat) {
	char bytes[32] = { 0 };

	char* inText = (char*)env->GetStringUTFChars(text, 0);
	int inLeng = env->GetStringLength(text);
	gRegDat = (regDat != NULL) ? (uint8_t*)env->GetDirectBufferAddress(regDat) : NULL;

	bytes[0] = 'd';
	bytes[1] = 'd';
	bytes[2] = 'd';
	bytes[3] = 0;
	CLOGD(TAG, "main AA");
	logd("main AAAA");
	//mainA();
	logd("main BBBC");
	memcpy(bytes, inText, inLeng);
	memcpy(bytes + inLeng, "a云控c", sizeof("a云控c"));
	return env->NewStringUTF(bytes);	// , "utf-8"
}


int main(int argc, char* argv[]) {
	uint32_t dnIpv4[8] = { 0 };
	CLOGD(TAG, "main AA");
	uint8_t dnQty = (uint8_t)PlatformGetGateway(NULL, dnIpv4, 8);
	if (dnQty > 0) {
		setInit(dnIpv4, dnQty);
		PlatformSleep(111);
		PlatformSleep(111);
		return true;
	}
	CLOGE(TAG, "main E");
	return 0;
}
